using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace AvalonEditDemo.Models
{
    /// <summary>
    /// 表示Python代码执行的结果，包含输出、错误信息和执行状态
    /// </summary>
    public class PythonExecutionResult
    {
        /// <summary>
        /// 获取或设置执行过程的标准输出内容
        /// </summary>
        public string Output { get; set; } = "";

        /// <summary>
        /// 获取或设置执行过程的错误输出内容
        /// </summary>
        public string Error { get; set; } = "";

        /// <summary>
        /// 获取或设置执行是否成功的标志
        /// </summary>
        public bool Success { get; set; } = true;

        /// <summary>
        /// 获取或设置代码执行所花费的时间
        /// </summary>
        public TimeSpan ExecutionTime { get; set; }
    }

    /// <summary>
    /// 提供Python代码执行功能的类，使用系统安装的Python解释器执行代码
    /// </summary>
    public class PythonExecutor
    {
        /// <summary>
        /// 初始化PythonExecutor的新实例
        /// </summary>
        public PythonExecutor()
        {
            // 初始化执行器
        }

        /// <summary>
        /// 修复Python代码的缩进问题，确保代码的缩进符合Python的语法要求
        /// </summary>
        /// <param name="code">需要修复缩进的Python代码</param>
        /// <returns>修复缩进后的Python代码</returns>
        private string FixIndentation(string code)
        {
            // 标准化行尾并分割为行
            var lines = code.Replace("\r\n", "\n").Split(new[] { '\n' });
            
            // 保存结果
            var result = new StringBuilder();
            
            // 跟踪缩进级别
            int expectedIndentation = 0;
            bool inMultiLineString = false;
            
            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];
                string trimmedLine = line.Trim();
                
                // 跳过空行
                if (string.IsNullOrWhiteSpace(trimmedLine))
                {
                    result.AppendLine();
                    continue;
                }
                
                // 检查多行字符串
                if (trimmedLine.Contains("'''") || trimmedLine.Contains("\"\"\""))
                {
                    // 简单处理：计算单行中三引号的出现次数
                    int count = Regex.Matches(trimmedLine, "'''|\"\"\"").Count;
                    if (count % 2 != 0) inMultiLineString = !inMultiLineString;
                }
                
                // 如果在多行字符串中，直接添加原始行
                if (inMultiLineString)
                {
                    result.AppendLine(line);
                    continue;
                }
                
                // 计算当前缩进
                int currentIndent = line.Length - trimmedLine.Length;
                
                // 检查行是否以冒号结尾（需要增加缩进）
                if (trimmedLine.EndsWith(":"))
                {
                    result.AppendLine(line);
                    expectedIndentation += 4;  // 增加缩进级别
                    continue;
                }
                
                // 检查是否需要减少缩进
                if (currentIndent < expectedIndentation && 
                    !trimmedLine.StartsWith("#") && 
                    !trimmedLine.StartsWith("else:") && 
                    !trimmedLine.StartsWith("elif ") && 
                    !trimmedLine.StartsWith("except ") && 
                    !trimmedLine.StartsWith("finally:"))
                {
                    // 调整预期缩进
                    expectedIndentation = (currentIndent / 4) * 4;
                }
                
                // 确保行有正确的缩进
                string indentation = new string(' ', expectedIndentation);
                result.AppendLine(indentation + trimmedLine);
            }
            
            return result.ToString();
        }

        /// <summary>
        /// 使用系统安装的Python解释器异步执行Python代码
        /// </summary>
        /// <param name="code">要执行的Python代码</param>
        /// <returns>包含执行结果的PythonExecutionResult对象</returns>
        public async Task<PythonExecutionResult> ExecuteWithSystemPythonAsync(string code)
        {
            // 首先应用缩进修复
            string fixedCode = FixIndentation(code);
            
            return await Task.Run(() =>
            {
                var result = new PythonExecutionResult();
                var stopwatch = new Stopwatch();
                
                try
                {
                    // 检查Python解释器是否可用
                    string pythonPath = "python";
                    bool pythonExists = false;
                    string versionOutput = "";
                    
                    try
                    {
                        // 尝试使用python命令检查解释器版本
                        using var checkProcess = new Process
                        {
                            StartInfo = new ProcessStartInfo
                            {
                                FileName = pythonPath,
                                Arguments = "--version",
                                UseShellExecute = false,
                                RedirectStandardOutput = true,
                                RedirectStandardError = true,
                                CreateNoWindow = true
                            }
                        };
                        
                        checkProcess.Start();
                        versionOutput = checkProcess.StandardOutput.ReadToEnd().Trim();
                        if (string.IsNullOrEmpty(versionOutput))
                            versionOutput = checkProcess.StandardError.ReadToEnd().Trim();
                        
                        checkProcess.WaitForExit();
                        pythonExists = checkProcess.ExitCode == 0;
                        
                        if (pythonExists)
                        {
                            result.Output = $"使用Python解释器: {versionOutput.Trim()}\n\n";
                        }
                    }
                    catch
                    {
                        pythonExists = false;
                    }
                    
                    if (!pythonExists)
                    {
                        // 尝试使用python3命令
                        try
                        {
                            pythonPath = "python3";
                            using var checkProcess = new Process
                            {
                                StartInfo = new ProcessStartInfo
                                {
                                    FileName = pythonPath,
                                    Arguments = "--version",
                                    UseShellExecute = false,
                                    RedirectStandardOutput = true,
                                    RedirectStandardError = true,
                                    CreateNoWindow = true
                                }
                            };
                            
                            checkProcess.Start();
                            versionOutput = checkProcess.StandardOutput.ReadToEnd().Trim();
                            if (string.IsNullOrEmpty(versionOutput))
                                versionOutput = checkProcess.StandardError.ReadToEnd().Trim();
                                
                            checkProcess.WaitForExit();
                            pythonExists = checkProcess.ExitCode == 0;
                            
                            if (pythonExists)
                            {
                                result.Output = $"使用Python解释器: {versionOutput.Trim()}\n\n";
                            }
                        }
                        catch
                        {
                            pythonExists = false;
                        }
                    }
                    
                    if (!pythonExists)
                    {
                        // 如果找不到Python解释器，返回错误信息
                        result.Error = "无法找到Python解释器。请确保已安装Python并添加到系统环境变量PATH中。";
                        result.Success = false;
                        return result;
                    }
                    
                    // 创建临时文件执行
                    string tempFilePath = Path.Combine(Path.GetTempPath(), $"python_code_{Guid.NewGuid():N}.py");
                    
                    // 使用经过修复缩进的代码
                    string cleanCode = fixedCode;
                    
                    // 打印调试信息
                    System.Diagnostics.Debug.WriteLine($"执行的代码:\n{cleanCode}");
                    
                    // 使用UTF8编码，不带BOM标记
                    File.WriteAllText(tempFilePath, cleanCode, new UTF8Encoding(false));

                    var outputBuilder = new StringBuilder();
                    var errorBuilder = new StringBuilder();

                    // 创建进程执行Python代码
                    using var process = new Process
                    {
                        StartInfo = new ProcessStartInfo
                        {
                            FileName = pythonPath,
                            Arguments = $"\"{tempFilePath}\"",
                            UseShellExecute = false,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            CreateNoWindow = true
                        }
                    };

                    // 捕获标准输出
                    process.OutputDataReceived += (_, e) => 
                    { 
                        if (e.Data != null) 
                            outputBuilder.AppendLine(e.Data); 
                    };
                    
                    // 捕获错误输出
                    process.ErrorDataReceived += (_, e) => 
                    { 
                        if (e.Data != null) 
                            errorBuilder.AppendLine(e.Data); 
                    };

                    // 执行Python代码并记录时间
                    stopwatch.Start();
                    process.Start();
                    
                    process.BeginOutputReadLine();
                    process.BeginErrorReadLine();
                    
                    process.WaitForExit();
                    stopwatch.Stop();

                    // 设置执行结果
                    result.Output += outputBuilder.ToString();
                    result.Error = errorBuilder.ToString();
                    result.Success = string.IsNullOrEmpty(result.Error) && process.ExitCode == 0;
                    result.ExecutionTime = stopwatch.Elapsed;

                    try
                    {
                        // 清理临时文件
                        File.Delete(tempFilePath);
                    }
                    catch
                    {
                        // 忽略删除临时文件的错误
                    }
                }
                catch (Exception ex)
                {
                    // 捕获所有异常
                    result.Error = ex.Message;
                    result.Success = false;
                    result.ExecutionTime = stopwatch.Elapsed;
                }

                return result;
            });
        }
    }
} 